﻿using Newtonsoft.Json;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Entities;
using Sustainalytics.Entities.ProductInvolvement;
using Sustainalytics.ScreeningTool.BL;
using Sustainalytics.ScreeningTool.BL.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using Sustainalytics.Utils;
using Sustainalytics.Entities.SustainableProducts;

namespace Sustainalytics.ScreeningTool.Service
{
    public class SelectedCriteriaDto
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Guid CriteriaLevel3Id { get; set; }
        public CriteriaTypeEnum Type { get; set; }
        public int Order { get; set; }
        public Guid? FilterGroupId { get; set; }

        public int TypeOneMinValue { get; set; }
        public int TypeOneMaxValue { get; set; }

        //used for CriteriaTypes with only one Element like 1,3,6
        public bool IsScreenable { get; set; }
        public CriteriaTypeIsNotScreenable TypeSixIsNotScreenableCriteriaItem { get; set; }
        public List<CriteriaType2IsScreenable> TypeTwoIsScreenableCriteriaItems { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeTwoIsNotScreenableCriteriaItems { get; set; }

        public string TypeThreeCollectionName { get; set; }
        public List<string> TypeThreeSelectedItems { get; set; }
        public List<CriteriaType3IsScreenable> TypeThreeIsScreenableCriteriaItems { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeThreeIsNotScreenableCriteriaItems { get; set; }

        public List<CriteriaTypeFourCategories> TypeFourCategories { get; set; }
        public string TypeFourSymbol;
        public bool TypeFourScreenOnAnyInvolvement { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeFourIsNotScreenableCriteriaItems { get; set; }
        
        public List<CriteriaType5IsScreenable> TypeFiveIsScreenableCriteriaItems {get; set;}
        public List<CriteriaTypeIsNotScreenable> TypeFiveIsNotScreenableCriteriaItems { get; set; }

        public int TypeSixMinValue { get; set; }
        public int TypeSixMaxValue { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeSixIsNotScreenableCriteriaItems { get; set; }


        public string TypeSevenCollectionName { get; set; }
        public List<string> TypeSevenSelectedItems { get; set; }

        public List<CriteriaType7IsScreenable> TypeSevenIsScreenableCriteriaItems { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeSevenIsNotScreenableCriteriaItems { get; set; }

        public List<CriteriaType8IsScreenable> TypeEightIsScreenableCriteriaItems { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeEightIsNotScreenableCriteriaItems { get; set; }

        public List<CriteriaType9IsScreenable> TypeNineIsScreenableCriteriaItems { get; set; }
        public List<CriteriaTypeIsNotScreenable> TypeNineIsNotScreenableCriteriaItems { get; set; }

        public List<CriteriaTypeIsNotScreenable> TypeTenIsNotScreenableCriteriaItems { get; set; }

        public int Type16MinValue { get; set; }
        public int Type16MaxValue { get; set; }
        public List<CriteriaTypeIsNotScreenable> Type16IsNotScreenableCriteriaItems { get; set; }

        public List<CriteriaType17IsScreenable> Type17IsScreenableCriteriaItems { get; set; }

        public List<CriteriaType25IsScreenable> Type25IsScreenableCriteriaItems { get; set; }

        public List<CriteriaTypeIsNotScreenable> Type25IsNotScreenableCriteriaItems { get; set; }

        #region Convert criteria to SelectedCriteriaDto
        public static SelectedCriteriaDto ConvertCriteriaTypeOneToSelectedCriteriaDto(FilterCriteria filterCriteria)
        {
            var minMax = new SelectedValueMinMax();

            if (!filterCriteria.IsDataPoint)
                minMax = JsonConvert.DeserializeObject<SelectedValueMinMax>(filterCriteria.SelectedValue);

            return new SelectedCriteriaDto()
            {
                Id = filterCriteria.TemplateCriteriaId,
                Name = filterCriteria.Name,
                FilterGroupId = filterCriteria.FilterGroupId,
                Type = filterCriteria.CriteriaType,
                TypeOneMaxValue = minMax.MaxValue,
                TypeOneMinValue = minMax.MinValue
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeTwoToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            List<CriteriaType2IsScreenable> TypeTwoIsScreenableCriteriaItems= new List<CriteriaType2IsScreenable>();
            List<CriteriaTypeIsNotScreenable> TypeTwoIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

                foreach (var item in listFilterCriteria)
                {
                    if (item.IsDataPoint)
                    {
                        TypeTwoIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = item.TemplateCriteriaId,
                            Name = item.Name,
                            IsDataPoint = item.IsDataPoint,
                            IsOn = true
                        });
                    }
                    else
                    {
                         SelectedValueScore score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                         TypeTwoIsScreenableCriteriaItems.Add(new CriteriaType2IsScreenable
                         {
                            Id = item.TemplateCriteriaId,
                            Name = item.Name,
                            Score = score != null ? score.Score : 0
                         });
                    }
                 }
                foreach (var template in listTemplateCriteria)
                {
                    if (template.IsScreenable)
                    {
                        if (TypeTwoIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                        {
                            TypeTwoIsScreenableCriteriaItems.Add(new CriteriaType2IsScreenable
                             {
                                 Id = template.Id,
                                 Name = template.Name,
                                 Score = 0
                             });
                        }
                    }
                    else
                    {
                        if (TypeTwoIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                        {
                            TypeTwoIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                            {
                                Id = template.Id,
                                Name = template.Name,
                                IsDataPoint = true,
                                IsOn = false
                            });
                        }
                    }
                }
                
            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType2,
                TypeTwoIsNotScreenableCriteriaItems = TypeTwoIsNotScreenableCriteriaItems,
                TypeTwoIsScreenableCriteriaItems = TypeTwoIsScreenableCriteriaItems
                
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeThreeToSelectedCriteriaDto(FilterCriteria filterCriteria)
        {
            var selectedItems = JsonConvert.DeserializeObject<SelectedValueSelectedItems>(filterCriteria.SelectedValue);
            return new SelectedCriteriaDto()
            {
                Id = filterCriteria.TemplateCriteriaId,
                Name = filterCriteria.Name,
                Type = filterCriteria.CriteriaType,
                FilterGroupId = filterCriteria.FilterGroupId,
                TypeThreeSelectedItems = selectedItems.SelectedItems,
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeThreeToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            var typeThreeIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();
            var typeThreeIsScreenableCriteriaItems = new List<CriteriaType3IsScreenable>();            

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    typeThreeIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    typeThreeIsScreenableCriteriaItems.Add(new CriteriaType3IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,                        
                    });
                }

            }
            
            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    if (typeThreeIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        typeThreeIsScreenableCriteriaItems.Add(new CriteriaType3IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name                            
                        });
                    }
                }
                else
                {
                    if (typeThreeIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        typeThreeIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            var selectedItems = JsonConvert.DeserializeObject<SelectedValueSelectedItems>(listFilterCriteria[0].SelectedValue);

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                Type = listFilterCriteria[0].CriteriaType,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                TypeThreeSelectedItems = selectedItems.SelectedItems,
                TypeThreeIsScreenableCriteriaItems = typeThreeIsScreenableCriteriaItems,
                TypeThreeIsNotScreenableCriteriaItems = typeThreeIsNotScreenableCriteriaItems
            };
        }
        
        public static SelectedCriteriaDto ConvertCriteriaTypeFourToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria, string name)
        {
            List<CriteriaTypeIsNotScreenable> TypeFourIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeFourIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (!template.IsScreenable)
                {
                    if (TypeFourIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeFourIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType4,
                TypeFourIsNotScreenableCriteriaItems = TypeFourIsNotScreenableCriteriaItems,
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeFiveToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria, ICompanyScreening blLayer)
        {
            List<CriteriaType5IsScreenable> TypeFiveIsScreenableCriteriaItems = new List<CriteriaType5IsScreenable>();
            List<CriteriaTypeIsNotScreenable> TypeFiveIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeFiveIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    SelectedValueScore score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                    var templateIndicatorNumber = item.Name.Split(' ').FirstOrDefault();
                    var indicatorTemplate = blLayer.GetIndicatorTemplate(templateIndicatorNumber);

                    TypeFiveIsScreenableCriteriaItems.Add(new CriteriaType5IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        Score = score.Score,
                        AnswerCategories = indicatorTemplate.AnswerCategories.ConvertAll(x => AnswerCategoryDto.ConvertAnswerCategoriesToDto(x))
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    var templateIndicatorNumber = template.Name.Split(' ').FirstOrDefault();
                    var indicatorTemplate = blLayer.GetIndicatorTemplate(templateIndicatorNumber);

                    if (TypeFiveIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeFiveIsScreenableCriteriaItems.Add(new CriteriaType5IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            Score = -1,
                            AnswerCategories = indicatorTemplate.AnswerCategories.ConvertAll(x => AnswerCategoryDto.ConvertAnswerCategoriesToDto(x))
                        });
                    }
                }
                else
                {
                    if (TypeFiveIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeFiveIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType5,
                TypeFiveIsNotScreenableCriteriaItems = TypeFiveIsNotScreenableCriteriaItems,
                TypeFiveIsScreenableCriteriaItems = TypeFiveIsScreenableCriteriaItems,
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaType25ToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria, ICompanyScreening blLayer)
        {
            List<CriteriaType25IsScreenable> Type25IsScreenableCriteriaItems = new List<CriteriaType25IsScreenable>();
            List<CriteriaTypeIsNotScreenable> Type25IsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    Type25IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    SelectedValueScore score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                    TemplateCriteria criteria = blLayer.GetTemplateCriteriaById(item.TemplateCriteriaId);

                    var editedCriteria = new CriteriaType25IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        Score = score.Score,
                        AnswerCategories = blLayer.GetAnswerCategoryForRiskRating(criteria).ConvertAll(x=> AnswerCategoryDto.ConvertAnswerCategoriesToDto(x))
                    };
                    editedCriteria.AnswerCategories.Add(new AnswerCategoryDto() { Score = -1, Text = "Off" });
                    Type25IsScreenableCriteriaItems.Add(editedCriteria);
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    if (Type25IsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        Type25IsScreenableCriteriaItems.Add(new CriteriaType25IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            Score = -1,
                            AnswerCategories = blLayer.GetAnswerCategoryForRiskRating(template).ConvertAll(x => AnswerCategoryDto.ConvertAnswerCategoriesToDto(x))
                        });
                    }
                }
                else
                {
                    if (Type25IsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        Type25IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType25,
                Type25IsNotScreenableCriteriaItems = Type25IsNotScreenableCriteriaItems,
                Type25IsScreenableCriteriaItems = Type25IsScreenableCriteriaItems,
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeSixToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            var type6IsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    type6IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (!template.IsScreenable)
                {
                    if (type6IsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        type6IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            var filterCriteria = listFilterCriteria[0];

            var minMax = new SelectedValueMinMax();

            if (!filterCriteria.IsDataPoint)
                minMax = JsonConvert.DeserializeObject<SelectedValueMinMax>(filterCriteria.SelectedValue);

            return new SelectedCriteriaDto()
            {
                Id = filterCriteria.TemplateCriteriaId,
                Name = filterCriteria.Name,
                FilterGroupId = filterCriteria.FilterGroupId,
                Type = filterCriteria.CriteriaType,
                TypeSixMaxValue = minMax.MaxValue,
                TypeSixMinValue = minMax.MinValue,
                IsScreenable = !filterCriteria.IsDataPoint,
                TypeSixIsNotScreenableCriteriaItems = type6IsNotScreenableCriteriaItems
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeSevenToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            List<CriteriaType7IsScreenable> TypeSevenIsScreenableCriteriaItems = new List<CriteriaType7IsScreenable>();
            List<CriteriaTypeIsNotScreenable> TypeSevenIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();
            SelectedValueSelectedItems selectedItems = new SelectedValueSelectedItems();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeSevenIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    selectedItems = JsonConvert.DeserializeObject<SelectedValueSelectedItems>(item.SelectedValue);

                    TypeSevenIsScreenableCriteriaItems.Add(new CriteriaType7IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    if (TypeSevenIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeSevenIsScreenableCriteriaItems.Add(new CriteriaType7IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                        });
                    }
                }
                else
                {
                    if (TypeSevenIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeSevenIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {

                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = listFilterCriteria[0].CriteriaType,
                TypeSevenSelectedItems = selectedItems.SelectedItems,
                TypeSevenIsScreenableCriteriaItems = TypeSevenIsScreenableCriteriaItems,
                TypeSevenIsNotScreenableCriteriaItems = TypeSevenIsNotScreenableCriteriaItems,
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeEightToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            List<CriteriaType8IsScreenable> TypeEightIsScreenableCriteriaItems = new List<CriteriaType8IsScreenable>();
            List<CriteriaTypeIsNotScreenable> TypeEightIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeEightIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    SelectedValueScore score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                    TypeEightIsScreenableCriteriaItems.Add(new CriteriaType8IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        Score = score.Score
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    if (TypeEightIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeEightIsScreenableCriteriaItems.Add(new CriteriaType8IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            Score = 0
                        });
                    }
                }
                else
                {
                    if (TypeEightIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeEightIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType8,
                TypeEightIsNotScreenableCriteriaItems = TypeEightIsNotScreenableCriteriaItems,
                TypeEightIsScreenableCriteriaItems = TypeEightIsScreenableCriteriaItems
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeNineToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            List<CriteriaType9IsScreenable> TypeNineIsScreenableCriteriaItems = new List<CriteriaType9IsScreenable>();
            List<CriteriaTypeIsNotScreenable> TypeNineIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeNineIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
                else
                {
                    SelectedValueScore score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                    TypeNineIsScreenableCriteriaItems.Add(new CriteriaType9IsScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        Score = score.Score
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (template.IsScreenable)
                {
                    if (TypeNineIsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeNineIsScreenableCriteriaItems.Add(new CriteriaType9IsScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            Score = 0
                        });
                    }
                }
                else
                {
                    if (TypeNineIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeNineIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType9,
                TypeNineIsNotScreenableCriteriaItems = TypeNineIsNotScreenableCriteriaItems,
                TypeNineIsScreenableCriteriaItems = TypeNineIsScreenableCriteriaItems
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaTypeTenToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            List<CriteriaTypeIsNotScreenable> TypeTenIsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    TypeTenIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (!template.IsScreenable) 
                {
                    if (TypeTenIsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        TypeTenIsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            return new SelectedCriteriaDto()
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType10,
                TypeTenIsNotScreenableCriteriaItems = TypeTenIsNotScreenableCriteriaItems,
            };
        }
        public static SelectedCriteriaDto ConvertCriteriaType16ToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria)
        {
            var type16IsNotScreenableCriteriaItems = new List<CriteriaTypeIsNotScreenable>();

            foreach (var item in listFilterCriteria)
            {
                if (item.IsDataPoint)
                {
                    type16IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                    {
                        Id = item.TemplateCriteriaId,
                        Name = item.Name,
                        IsDataPoint = item.IsDataPoint,
                        IsOn = true
                    });
                }
            }

            foreach (var template in listTemplateCriteria)
            {
                if (!template.IsScreenable)
                {
                    if (type16IsNotScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                    {
                        type16IsNotScreenableCriteriaItems.Add(new CriteriaTypeIsNotScreenable
                        {
                            Id = template.Id,
                            Name = template.Name,
                            IsDataPoint = true,
                            IsOn = false
                        });
                    }
                }
            }

            var filterCriteria = listFilterCriteria[0];

            var minMax = new SelectedValueMinMax();

            if (!filterCriteria.IsDataPoint)
                minMax = JsonConvert.DeserializeObject<SelectedValueMinMax>(filterCriteria.SelectedValue);

            return new SelectedCriteriaDto()
            {
                Id = filterCriteria.TemplateCriteriaId,
                Name = filterCriteria.Name,
                FilterGroupId = filterCriteria.FilterGroupId,
                Type = filterCriteria.CriteriaType,
                Type16MaxValue = minMax.MaxValue,
                Type16MinValue = minMax.MinValue,
                Type16IsNotScreenableCriteriaItems = type16IsNotScreenableCriteriaItems
            };
        }

        public static SelectedCriteriaDto ConvertCriteriaType17ToSelectedCriteriaDto(List<FilterCriteria> listFilterCriteria, List<TemplateCriteria> listTemplateCriteria, ICompanyScreening _blLayer)
        {
            string templateIndicatorNumber = String.Empty;
            if (listTemplateCriteria.Any())
                templateIndicatorNumber = listTemplateCriteria.First().Name.Split(' ').FirstOrDefault();

            var indicatorTemplate = _blLayer.GetGovernanceIndicatorTemplate(templateIndicatorNumber);

            var answerCategories = indicatorTemplate.AnswerCategories.ConvertAll(x => AnswerCategoryDto.ConvertAnswerCategoriesToDto(x));
            answerCategories.Add(new AnswerCategoryDto() { Text = "Off", Score = -1 });
            
            var type17IsScreenableCriteriaItems = new List<CriteriaType17IsScreenable>();

            foreach (var item in listFilterCriteria)
            {
                var score = JsonConvert.DeserializeObject<SelectedValueScore>(item.SelectedValue);
                type17IsScreenableCriteriaItems.Add(new CriteriaType17IsScreenable
                {
                    Id = item.TemplateCriteriaId,
                    Name = item.Name,
                    Score = score.Score,
                    AnswerCategories = answerCategories,
                });
            }

            foreach (var template in listTemplateCriteria)
            {
                if (type17IsScreenableCriteriaItems.FirstOrDefault(x => x.Id == template.Id) == null)
                {
                    type17IsScreenableCriteriaItems.Add(new CriteriaType17IsScreenable
                    {
                        Id = template.Id,
                        Name = template.Name,
                        Score = 0,
                        AnswerCategories = answerCategories,
                    });
                }
            }

            return new SelectedCriteriaDto
            {
                Id = listFilterCriteria[0].TemplateCriteriaId,
                Name = listFilterCriteria[0].Name,
                FilterGroupId = listFilterCriteria[0].FilterGroupId,
                Type = CriteriaTypeEnum.CriteriaType17,
                Type17IsScreenableCriteriaItems = type17IsScreenableCriteriaItems
            };
        }


        #endregion
    }

    public class CriteriaTypeFourCategories
    {
        public string Symbol { get; set; }
        public string CategoryOfInvolvement { get; set; }
        public string CategorySymbol { get; set; }
        public int MaxValue { get; set; }
        public double SelectedValue { get; set; }
        public bool IsSignificantOwnership { get; set; }
        public bool SignificantOwnershipYesNo { get; set; }
        public bool RevenueRangeYesNo { get; set; }
        public bool IsInvolved { get; set; }
        public List<PIRangeDto> RevenueRange { get; set; }
        private CriteriaTypeFourCategories() { }
        public Guid TemplateCriteriaId { get; set; }

        public static CriteriaTypeFourCategories CreateComplete(ProductInvolvementCategory category, Guid templateCriteriaId, FilterCriteria filterCriteria)
        {
            List<PIRangeDto> revenueRange = new List<PIRangeDto>();
            if (category.RevenueRangeYesNo && category.RevenueRange.Any(rr => !rr.Value.NA))
                revenueRange = category.RevenueRange.Values.ToList().ConvertAll<PIRangeDto>(rr => PIRangeDto.CreateComplete(rr));
            
            if (filterCriteria == null)
            {
                return new CriteriaTypeFourCategories()
                {
                    CategoryOfInvolvement = category.CategoryOfInvolvement,
                    SignificantOwnershipYesNo = category.OwnershipYesNo,
                    IsSignificantOwnership = false,
                    IsInvolved = false,
                    RevenueRangeYesNo = category.RevenueRangeYesNo,
                    RevenueRange = revenueRange,
                    SelectedValue = -1,
                    MaxValue = GetMaxValueFromRevenueRange(category.RevenueRange.Values.ToList()),
                    CategorySymbol = category.Symbol,
                    TemplateCriteriaId = templateCriteriaId
                };
            }
            else
            {
                CriteriaTypeFour selectedValue = JsonConvert.DeserializeObject<CriteriaTypeFour>(filterCriteria.SelectedValue);

                return new CriteriaTypeFourCategories()
                {
                    SelectedValue = !selectedValue.PiFilterCriteriaRange.Stop.NearlyEq(0) ? selectedValue.PiFilterCriteriaRange.Start : -1,
                    CategoryOfInvolvement = category.CategoryOfInvolvement,
                    SignificantOwnershipYesNo = category.OwnershipYesNo,
                    IsInvolved = selectedValue.PiFilterCriteriaRange.IsInvolvement,
                    IsSignificantOwnership = selectedValue.PiFilterCriteriaRange.IsSignificantOwnership,
                    RevenueRangeYesNo = category.RevenueRangeYesNo,
                    RevenueRange = revenueRange,
                    MaxValue = GetMaxValueFromRevenueRange(category.RevenueRange.Values.ToList()),
                    CategorySymbol = category.Symbol,
                    TemplateCriteriaId = templateCriteriaId
                };
            }
        }

        public static CriteriaTypeFourCategories CreateComplete(SustainableProductsCategory category, Guid templateCriteriaId, FilterCriteria filterCriteria)
        {
            List<PIRangeDto> revenueRange = new List<PIRangeDto>();
            if (category.RevenueRange.Any(rr => !rr.Value.NA))
                revenueRange = category.RevenueRange.Values.ToList().ConvertAll<PIRangeDto>(rr => PIRangeDto.CreateComplete(rr));

            if (filterCriteria == null)
            {
                return new CriteriaTypeFourCategories()
                {
                    CategoryOfInvolvement = category.CategoryOfInvolvement,
                    IsSignificantOwnership = false,
                    IsInvolved = false,
                    RevenueRange = revenueRange,
                    RevenueRangeYesNo = true,
                    SelectedValue = -1,
                    MaxValue = GetMaxValueFromRevenueRange(category.RevenueRange.Values.ToList()),
                    CategorySymbol = category.Symbol,
                    TemplateCriteriaId = templateCriteriaId
                };
            }
            else
            {
                CriteriaTypeFour selectedValue = JsonConvert.DeserializeObject<CriteriaTypeFour>(filterCriteria.SelectedValue);

                return new CriteriaTypeFourCategories()
                {
                    SelectedValue = !selectedValue.PiFilterCriteriaRange.Stop.NearlyEq(0) ? selectedValue.PiFilterCriteriaRange.Start : -1,
                    CategoryOfInvolvement = category.CategoryOfInvolvement,
                    IsInvolved = selectedValue.PiFilterCriteriaRange.IsInvolvement,
                    IsSignificantOwnership = selectedValue.PiFilterCriteriaRange.IsSignificantOwnership,
                    RevenueRange = revenueRange,
                    RevenueRangeYesNo = true,
                    MaxValue = GetMaxValueFromRevenueRange(category.RevenueRange.Values.ToList()),
                    CategorySymbol = category.Symbol,
                    TemplateCriteriaId = templateCriteriaId
                };
            }
        }

        public static int GetMaxValueFromRevenueRange(List<PIRange> piRange)
        {
            var lastPIRange = piRange.OrderBy(rr => rr.RangeId).LastOrDefault(rr => rr.NA);
            if (lastPIRange != null)
                return 5 - lastPIRange.RangeId;

            return 5;
        }
    }

    public class PIRangeDto
    {
        public int RangeId { get; set; }
        public bool NA { get; set; }
        public double Start { get; set; }
        public double Stop { get; set; }

        private PIRangeDto() { }

        public static PIRangeDto CreateComplete(PIRange range)
        {
            if (range == null)
                throw new ArgumentNullException("PIRange", "The PIRange cannot be null.");

            return new PIRangeDto()
            {
                RangeId = range.RangeId,
                NA = range.NA,
                Start = range.Start,
                Stop = range.Stop
            };
        }
    }
}
